package Attributes;

import Attributes.getSongAttributes;
import Attributes.AttributeCleaner;
import Database.SongIDCounter;
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.apache.commons.io.FilenameUtils;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import org.jaudiotagger.tag.TagField;
import org.jaudiotagger.tag.id3.AbstractID3v2Tag;
import org.jaudiotagger.tag.id3.ID3v24Frames;
import org.jaudiotagger.tag.mp4.Mp4FieldKey;
import org.jaudiotagger.tag.mp4.Mp4Tag;

public class LibraryMetadataExtract {

    private static String Location = "Directory";
    File songFile;

    public LibraryMetadataExtract(File f) {
        songFile = f;
    }

    public void extract() {
        System.out.println("LibraryMetadataExtract.extract()");
        if (FilenameUtils.isExtension(songFile.getAbsolutePath(), "mp3")) {
            String artist = "Unknown",
                    title = "Unknown",
                    album = "Unknown",
                    genre = "Unknown",
                    bpm = "Unknown",
                    theKey = "Unknown",
                    image = "",
                    danceability = "Unknown",
                    energy = "Uknown",
                    acousticness = "Unkown";
            MP3File g = null;

            try {
                g = (MP3File) AudioFileIO.read(songFile);
            } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException ex) {
                Logger.getLogger(LibraryMetadataExtract.class.getName()).log(Level.SEVERE, null, ex);
            }

            AbstractID3v2Tag v2tag;
            try {
                v2tag = g.getID3v2Tag();
                title = v2tag.getFirst(ID3v24Frames.FRAME_ID_TITLE);
                artist = v2tag.getFirst(ID3v24Frames.FRAME_ID_ARTIST);
                album = v2tag.getFirst(ID3v24Frames.FRAME_ID_ALBUM);
                genre = v2tag.getFirst(ID3v24Frames.FRAME_ID_GENRE);
                bpm = v2tag.getFirst(ID3v24Frames.FRAME_ID_BPM);
                theKey = v2tag.getFirst(ID3v24Frames.FRAME_ID_INITIAL_KEY);
                System.out.println("-----------------------Key----------------------------"+ theKey);

            } catch (Exception ex) {
                Logger.getLogger(LibraryMetadataExtract.class.getName()).log(Level.SEVERE, null, ex);
            }

            ArrayList<String> valSet;
            valSet = getSongAttributes.parseXml(artist, title, true);
            if (bpm.equals("")) {
                bpm = AttributeCleaner.clean(valSet.get(2));
            }
            if (theKey.equals("")) {
                bpm = AttributeCleaner.clean(valSet.get(2));
            }
            theKey = AttributeCleaner.clean(valSet.get(3));
            danceability = AttributeCleaner.clean(valSet.get(4));
            energy = AttributeCleaner.clean(valSet.get(5));
            acousticness = AttributeCleaner.clean(valSet.get(6));
            if (album.equals("") || album == null) {
                album = AttributeCleaner.clean(valSet.get(7));
            }
            if (AttributeCleaner.clean(valSet.get(8)) != null) {
                genre = AttributeCleaner.clean(valSet.get(8));
            }
            String FilePathway = songFile.getAbsolutePath().replaceAll("'", "~");
            //System.out.println(FilePathway);
            SongIDCounter.Add_To_Song_ID_Count();
            String Song_ID = SongIDCounter.ID();
            image = songFile.getPath();
            Mp3File song = null;
            try {
                song = new Mp3File(image);
                ID3v2 id3v2tag = song.getId3v2Tag();
                byte[] imData = id3v2tag.getAlbumImage();
                getAlbumArt.SaveImageFromLibrary(imData, album, artist, title);
            } catch (IOException | UnsupportedTagException | InvalidDataException ex) {
                image = getAlbumArt.NewDir(title, artist, album);
            }
            System.out.println(title);

            ArrayList set = new ArrayList();
            set.add(Song_ID);
            set.add(title);
            set.add(artist);
            set.add(album);
            set.add(genre);
            set.add(energy);
            set.add(danceability);
            set.add(acousticness);
            set.add(getSongAttributes.BPM(bpm));
            set.add(theKey);
            set.add(image);
            set.add(FilePathway);
            LibraryDataSets.InsertLibraryToDatabase(set);
        } else if (FilenameUtils.isExtension(songFile.getAbsolutePath(), "m4a")) {
            String artist = "Unknown",
                    title = "Unknown",
                    album = "Unknown",
                    genre = "Unknown",
                    bpm = "Unknown",
                    theKey = "Unknown",
                    image = "",
                    danceability = "Unknown",
                    energy = "Uknown",
                    acousticness = "Unkown";

            //Mp4Tag mp4tag = (Mp4Tag) audiofile.getTag();
            Tag tag;
            try {
                tag = AudioFileIO.read(songFile).getTag();
                title = tag.getFirst(FieldKey.TITLE);
                System.out.println("Tag Title - " + title);
                artist = tag.getFirst(FieldKey.ARTIST);
                System.out.println("Tag artist - " + artist);
                album = tag.getFirst(FieldKey.ALBUM);
                System.out.println("Tag album - " + album);
                genre = tag.getFirst(FieldKey.GENRE);
                System.out.println("Tag genre - " + genre);
                bpm = getSongAttributes.BPM(tag.getFirst(FieldKey.BPM));
                System.out.println("Tag bpm - " + bpm);
                theKey = tag.getFirst(FieldKey.KEY).replace("m", "");
                System.out.println("Tag Key - " + theKey);
            } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException ex) {
                //Logger.getLogger(LibraryMetadataExtract.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
            }
            ArrayList<String> valSet;
            if (album.equals("") || genre.equals("") || bpm.equals("") || theKey.equals("")) {
                valSet = getSongAttributes.parseXml(artist, title, false);

                if (valSet != null) {
                    if (bpm.equals("")) {
                        bpm = AttributeCleaner.clean(valSet.get(2));
                    }
                    theKey = AttributeCleaner.clean(valSet.get(3));
                    danceability = AttributeCleaner.clean(valSet.get(4));
                    energy = AttributeCleaner.clean(valSet.get(5));
                    acousticness = AttributeCleaner.clean(valSet.get(6));
                    if (album.equals("") || album == null) {
                        album = AttributeCleaner.clean(valSet.get(7));
                    }
                    if (AttributeCleaner.clean(valSet.get(8)) != null) {
                        genre = AttributeCleaner.clean(valSet.get(8));
                    }
                }
            } else {
                getSongAttributes attr = new getSongAttributes();
                attr.theInfo(artist, title);
                danceability = attr.Dance();
                energy = attr.EnergyAmount();
                acousticness = attr.Acoustic();
            }
            String FilePathway = songFile.getAbsolutePath().replaceAll("'", "~");
            System.out.println(FilePathway);

            SongIDCounter.Add_To_Song_ID_Count();
            String Song_ID = SongIDCounter.ID();
            image = getAlbumArt.NewDir(title, artist, album);

            System.out.println(title);
            ArrayList set = new ArrayList();
            set.add(Song_ID);
            set.add(title);
            set.add(artist);
            set.add(album);
            set.add(genre);
            set.add(energy);
            set.add(danceability);
            set.add(acousticness);
            set.add(bpm);
            set.add(theKey);
            set.add(image);
            set.add(FilePathway);
            LibraryDataSets.InsertLibraryToDatabase(set);
        }
    }
}
